import { tt } from './types.js';
function isNewLine(code) {
    switch (code) {
        case 10:
        case 13:
        case 8232:
        case 8233:
            return true;
        default:
            return false;
    }
}
class ParserJs {
    constructor(input) {
        this.input = input;
        this.length = this.input.length;
        this.cur = 0;
        this.curLine = 0;
        this.tokens = [];
    }
    parser() {
        this.nextToken();
    }
    nextToken() {
        this.skipSpace();
        if (this.cur >= this.length) {
            return;
        }
        console.log(this.cur)
        this.getTokenFromCode(this.input.charCodeAt(this.cur));
    }

    /**
     * 判断是否是字符
     * @param {*} code 
     * @returns 
     */
    isIdentifierChar(code) {
        if (code < 48) return code === 36;
        if (code < 58) return true;
        if (code < 65) return false;
        if (code <= 90) return true;
        if (code < 97) return code === 95;
        if (code <= 122) return true;
    }
    /**
     *  处理 注释的内容
     */
    skipBlockComment() {
        const start = this.cur;
        const end = this.input.indexOf("*/", start + 2);
        if (end === -1) {
            throw new Error(`注释错误 :in ${this.curLine} column,iin ${this.cur} row`);
        }
        this.cur = end + 2;
    }
    /**
     * 处理注释的内容
     * @param {*} startSkip 
     */
    skipLineComment(startSkip) {
        const start = this.cur;
        if (!this.isLookahead) startLoc = this.state.curPosition();
        let ch = this.input.charCodeAt(this.state.pos += startSkip);

        if (this.cur < this.length) {
            while (!isNewLine(ch) && ++this.cur < this.length) {
                ch = this.input.charCodeAt(this.cur);
            }
        }
    }
    /**
     * 处理换行，空格 注释
     */
    skipSpace() {
        loop: while (this.cur < this.length) {
            const ch = this.input.charCodeAt(this.cur);
            switch (ch) {
                case 32:
                case 160:
                case 9:
                    ++this.cur;
                    break;

                case 13:
                    if (this.input.charCodeAt(this.cur + 1) === 10) {
                        ++this.cur;
                    }

                case 10:
                case 8232:
                case 8233:
                    ++this.cur;
                    ++this.curLine;
                    break;

                case 47:
                    switch (this.input.charCodeAt(this.cur + 1)) {
                        case 42:
                            {
                                this.skipBlockComment();
                                break loop;
                            }

                        case 47:
                            {
                                this.skipLineComment(2);
                                break loop;
                            }

                        default:
                            break loop;
                    }

                    break;

                default:
                    break loop;
                // if (this.isWhitespace(ch)) {
                //     ++this.state.pos;
                // } else if (ch === 45 && !this.inModule) {
                //     const pos = this.state.pos;

                //     if (this.input.charCodeAt(pos + 1) === 45 && this.input.charCodeAt(pos + 2) === 62 && (spaceStart === 0 || this.state.lineStart > spaceStart)) {
                //         const comment = this.skipLineComment(3);

                //         if (comment !== undefined) {
                //             this.addComment(comment);
                //             if (this.options.attachComment) comments.push(comment);
                //         }
                //     } else {
                //         break loop;
                //     }
                // } else if (ch === 60 && !this.inModule) {
                //     const pos = this.state.pos;

                //     if (this.input.charCodeAt(pos + 1) === 33 && this.input.charCodeAt(pos + 2) === 45 && this.input.charCodeAt(pos + 3) === 45) {
                //         const comment = this.skipLineComment(4);

                //         if (comment !== undefined) {
                //             this.addComment(comment);
                //             if (this.options.attachComment) comments.push(comment);
                //         }
                //     } else {
                //         break loop;
                //     }
                // } else {
                //     break loop;
                // }

            }
        }
    }

    /**
     * 读取文字内容
     * @param {*} firstCode 
     */
    readWord(firstCode) {
        const startPos = this.cur;
        while (this.cur < this.length) {
            const ch = this.input.charCodeAt(this.cur);
            if (this.isIdentifierChar(ch)) {
                ++this.cur;
            } else {
                const word = this.input.slice(startPos, this.cur);
                this.finshToken(word);
            }
        }
    }
    /**
     * 点
     * @param {*} code 
     */
    readDot(code) {
        ++this.cur;
    }
    isStringEnd(type, ch, input, pos) {
        if (type === "template") {
            return ch === 96 || ch === 36 && input.charCodeAt(pos + 1) === 123;
        }

        return ch === (type === "double" ? 34 : 39);
    }
    readStringContents(type, input, pos, curLine) {
        const length = input.length;
        let out = '';
        let chunkStart = pos;
        for (; ;) {
            if (pos >= length) {
                throw new Error(`字符串错误: 第 ${curLine} column,第 ${pos} row`);
                return;
            }
            const ch = input.charCodeAt(pos);
            if (this.isStringEnd(type, ch, input, pos)) {
                out += input.slice(chunkStart, pos);
                break;
            }
            if (ch === 10 || ch === 13) {
                if (type === 'template') {
                    out += input.slice(chunkStart, pos) + "\n";
                    ++pos;
                    if (ch === 13 && input.charCodeAt(pos) === 10) {
                        ++pos;
                    }
                    curLine++;
                } else {
                    throw new Error(`当前字符串出现错误：第${curLine} column,第 ${pos} row`)
                }

            } else {
                ++pos;
            }
        }
        return {
            str: out,
            pos,
            curLine
        }
    }
    readString(quote) {
        const {
            str,
            pos,
            curLine
        } = this.readStringContents(quote === 34 ? "double" : "single", this.input, this.cur + 1, this.curLine);
        this.cur = pos + 1;
        this.curLine = curLine;
        this.finshToken(str);
    }
    finshToken(str) {
        console.log(str);
        this.nextToken();
    }
    getTokenFromCode(code) {
        console.log(code)
        switch (code) {
            case 33: // !
            case 35: // #
            case 37: // %
                ++this.cur;
                this.nextToken();
                break;
            case 34: // "
            case 39: // '
                this.readString(code);
                return;
            case 40: // (
                ++this.cur;
                this.finshToken(tt.parenL);
            case 41: // )
                ++this.cur;
                this.finshToken(tt.parenR);
            case 42: // *
            case 43: // +
            case 44: // ,
            case 45: // -
            case 47: // /
            case 46: // .
            case 48: // 0
            case 49: // 1
            case 50: // 2
            case 51: // 3
            case 52: // 4
            case 53: // 5
            case 54: // 6
            case 55: // 7
            case 56: // 8                           
            case 57: // 9
            case 58: // :
            case 59: // ;
            case 60: // <
            case 61: // =
            case 62: // >
            case 63: // ?
            case 64: // @
            case 91: // [
            case 92: // \
            case 93: // ]
                ++this.cur;
                this.nextToken();
                break;
            case 96: // `
                this.readString(code)
            case 123: // {

            case 124: // |
            case 125: // }   
            case 126: // ~   
                ++this.cur;
                this.nextToken();
                break;
            default:
                this.readWord(code);
        }
    }
}
module.exports = ParserJs;